#include "app_buffer.h"
#include "log/log.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>

static SubBuffer *sub_buffer_init(int total_size)
{
    SubBuffer *sub_buffer = (SubBuffer *)malloc(sizeof(SubBuffer));
    if (sub_buffer == NULL)
        log_error("malloc sub_buffer failed");
    sub_buffer->ptr = malloc(total_size);
    sub_buffer->total_size = total_size;
    sub_buffer->len = 0;
    return sub_buffer;
}
Buffer *app_buffer_init(int total_size)
{
    // 分配大缓冲区内存
    Buffer *buffer = (Buffer *)malloc(sizeof(Buffer));
    if (buffer == NULL)
        log_error("malloc buffer failed");
    // 初始化小缓冲区 添加到大缓冲区中
    buffer->sub_buffers[0] = sub_buffer_init(total_size);
    buffer->sub_buffers[1] = sub_buffer_init(total_size);
    buffer->read_index = 0;
    buffer->write_index = 1;
    // 初始化锁
    pthread_mutex_init(&buffer->read_lock, NULL);
    pthread_mutex_init(&buffer->write_lock, NULL);
    return buffer;
}

void app_buffer_free(Buffer *buffer)
{
    // 释放小缓冲区内存
    free(buffer->sub_buffers[0]->ptr);




















    
    free(buffer->sub_buffers[1]->ptr);
    // 释放小缓冲区
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]);
    // 释放大缓冲区
    free(buffer);
}

int app_buffer_write(Buffer *buffer, char *data, int data_len)
{
    if (data_len > 255) // 用一个字节存储数据长度
    {
        log_error("写入数据超过一个字节");
        return -1;
    }
    log_debug("准备写入数据 %.*s，数据长度 %d", data_len, data, data_len);
    // 加锁
    pthread_mutex_lock(&buffer->write_lock);
    // 获取写小缓冲区
    SubBuffer *w_buffer = buffer->sub_buffers[buffer->write_index];
    // 如果写缓冲区剩余空间不够，则错误退出
    if (data_len > w_buffer->total_size - w_buffer->len - 1)
    {
        log_error("写缓冲区剩余空间不足");
        pthread_mutex_unlock(&buffer->write_lock);
        return -1;
    }
    // 写入数据 先写数据长度(一个字节)，再写数据
    w_buffer->ptr[w_buffer->len] = data_len;
    memcpy(&(w_buffer->ptr[w_buffer->len + 1]), data, data_len);
    // 更新写缓冲区的数据长度
    w_buffer->len += data_len + 1;
    // 解锁
    pthread_mutex_unlock(&buffer->write_lock);
    log_debug("写入数据完成 %.*s", data_len, data);
    return 0;
}

static void switch_buffer(Buffer *buffer)
{
    log_debug("准备切换缓冲区");
    // 加写锁           ?读？
    pthread_mutex_lock(&buffer->write_lock);
    int temp = buffer->read_index;
    buffer->read_index = buffer->write_index;
    buffer->write_index = temp;
    // 解锁
    pthread_mutex_unlock(&buffer->write_lock);

    log_debug("切换缓冲区完成");
}

int app_buffer_read(Buffer *buffer, char *data_buf, int buf_len)
{
    pthread_mutex_lock(&buffer->read_lock);
    log_debug("准备读取数据");
    // 获取读小缓冲区
    SubBuffer *r_buffer = buffer->sub_buffers[buffer->read_index];
    // 在准备读之前，如果缓冲区没有数据，切换缓冲区
    if (r_buffer->len == 0)
    {
        switch_buffer(buffer);
        // 重新获取缓冲区
        r_buffer = buffer->sub_buffers[buffer->read_index];
        // 如果还是没有数据，错误退出
        if (r_buffer->len == 0)
        {
            log_error("读缓冲区没有数据");
            pthread_mutex_unlock(&buffer->read_lock);
            return -1;
        }
    }
    // 读取数据，并保持到 data_buff
    //  先得到数据长度 内存的第一个字节
    int data_len = r_buffer->ptr[0];
    // 如果数据长度大于buf_len,错误退出
    if (buf_len < data_len)
    {
        log_error("要读取的数据长度大于buf_size");
        pthread_mutex_unlock(&buffer->read_lock);
        return -1;
    }
    // 根据长度读取数据
    memcpy(data_buf, &r_buffer->ptr[1], data_len);
    // 将第一帧后面的所有数据移动到起始的位置
    memmove(&r_buffer->ptr[0], &r_buffer->ptr[data_len + 1], r_buffer->total_size - data_len - 1);
    // 更新读缓冲区的数据长度
    r_buffer->len -= (data_len + 1);
    log_debug("读取数据完成 %.*s", data_len, data_buf);
    pthread_mutex_unlock(&buffer->read_lock);
    // 读取完成后，如果缓冲区没有数据，切换缓冲区
    if (r_buffer->len == 0)
    {
        switch_buffer(buffer);
    }
    // 返回读取数据的长度
    return data_len;
}
